package org.water.common.shiro.filter;

import java.io.IOException;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.shiro.web.filter.authz.HttpMethodPermissionFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMethod;
import org.water.base.entity.R;
import org.water.common.bind.method.ResultFormatReturnValue;
import org.water.common.exception.SysCode;
import org.water.common.param.AppSysParam;
import org.water.common.param.ConstParams;
import org.water.sys.service.ResourceService;
/**
 * 接口认证
 * @author qzy
 *
 */
public class ApiAuthFilter extends HttpMethodPermissionFilter {
	
	@Autowired
	ResourceService resourceService;
	
	static Logger log=LogManager.getLogger(ApiAuthFilter.class);
	/**
	 * 否认访问
	 */
	@Override
	protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws IOException {
		HttpServletRequest httpRequest=(HttpServletRequest) request;
		HttpServletResponse httpResponse=(HttpServletResponse) response;
		if(httpRequest.getMethod().equals(RequestMethod.OPTIONS.name())) {
			httpResponse.setStatus(HttpStatus.OK.value());
            return true;
        }
		ResultFormatReturnValue.instance().setResultValue(R.instance().setCode(SysCode.nologin.getCode()).setMsg(SysCode.nologin.getMsg()), 
				(HttpServletRequest) request, (HttpServletResponse) response);
		return false;
	}
	/**
	 * 是否允许访问
	 */
	@Override
	public boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue)
			throws IOException {
		boolean result=super.isAccessAllowed(request, response, mappedValue);
		if(result==false) return false;
		
		Object validate=AppSysParam.getProp("auth.api.valiate");
		if(validate!=null && validate.equals("true"))//接口需要验证时处理
		{
			HttpServletRequest httpRequest=(HttpServletRequest) request;
			String url=httpRequest.getRequestURI();
			if(url.contains(";"))
			{
				url=url.substring(0, url.indexOf(";"));
			}
			if(url.contains("?"))
			{
				url=url.substring(0, url.indexOf("?"));
			}
			String context=httpRequest.getContextPath();
			if(!StringUtils.isEmpty(context) && !"/".equalsIgnoreCase(context))//去掉上下文路径
			{
				url=url.replace(context, "");
			}
			String userId=(String) httpRequest.getSession().getAttribute(ConstParams.CURRENT_USER_ID);
			String userName=(String) httpRequest.getSession().getAttribute(ConstParams.CURRENT_USERNAME);
			return authValidateUrl(url,userId,userName);
		}
		else
		{
			return result;
		}
	}
	/**
	 * 验证用户访问接口权限
	 * @param url
	 * @return
	 */
	protected boolean authValidateUrl(String url,String userId,String userName)
	{
		boolean result=false;
		Object validate=AppSysParam.getProp("auth.api.valiate");
		if(validate!=null && validate.equals("true"))
		{
			List<Map<String, Object>> resources=resourceService.findApisByUserId(userId);
			if(resources!=null && !resources.isEmpty())
			{
				for(Map<String, Object> res:resources)
				{
					if(res.get("apis")!=null && ((String) res.get("apis")).contains(url))
					{
						result=true;
						break;
					}
				}
			}
		}
		else
		{
			result=true;
		}
		if(result==false)
		{
			log.info(userName+" 访问未授权的url:"+url);
		}
		return result;
	}
	/**
	 * 跳转到退出页面
	 */
	protected void redirectToLogout(ServletRequest request, ServletResponse response)
	{
		String logoutUrl=getUnauthorizedUrl();
	    try {
			WebUtils.issueRedirect(request, response, logoutUrl);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}
